home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 June
/
EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso
/
earcd
/
utilmus
/
mod2smp.lha
/
source
/
mix.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-26
|
28KB
|
1,049 lines
#define MAXIM 0x10000
#define VBLVAL 70938
#define VBLVALNTSC 71591
#define CIAVAL 1773447
#define CIAVALNTSC 1789772
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<proto/exec.h>
#include<exec/memory.h>
#include<proto/dos.h>
#include<proto/exec.h>
#include<proto/intuition.h>
#include<proto/gadtools.h>
#include<proto/reqtools.h>
#include<proto/graphics.h>
#include<devices/audio.h>
#include<libraries/reqtools.h>
#include<thom/thomdos.h>
#include"mix_rev.h"
#include"gadtools.h"
char ver[]=VERSTAG;
#define ABOUTTXT "Mod2Samp v0.78g\nby\nHali/Union\n\nGUI by Thom/Union"
// prototypy
void main(int,char **);
ULONG mixer(struct kupa);
void adresysampli(BYTE *,struct sampel *,UWORD);
void HandleMainWnd(void);
void Work(void);
void RequestOK(char *);
void RequestAbout(void);
void PrintNote(ULONG);
void LoadModule(char *);
void SaveSample(char *);
void FreeMemory(void);
void Status(char *);
BOOL OpenAudio(void);
void CloseAudio(void);
void Play(void);
void adresysampli(BYTE *,struct sampel *,UWORD);
UWORD policzpatterny(BYTE *);
void SetDefault(APTR);
void SetTitle(void);
WORD calculate_pom(WORD,WORD,ULONG,ULONG,UBYTE);
WORD findperiod(WORD,BYTE,BYTE);
struct notes
{
char a[4];
};
WORD periodtab[16][12*3]={
{ 856,808,762,720,678,640,604,570,538,508,480,453, // Tuning 0, Normal
428,404,381,360,339,320,302,285,269,254,240,226,
214,202,190,180,170,160,151,143,135,127,120,113},
{ 850,802,757,715,674,637,601,567,535,505,477,450, // Tuning 1
425,401,379,357,337,318,300,284,268,253,239,225,
213,201,189,179,169,159,150,142,134,126,119,113},
{ 844,796,752,709,670,632,597,563,532,502,474,447, // Tuning 2
422,398,376,355,335,316,298,282,266,251,237,224,
211,199,188,177,167,158,149,141,133,125,118,112},
{ 838,791,746,704,665,628,592,559,528,498,470,444, // Tuning 3
419,395,373,352,332,314,296,280,264,249,235,222,
209,198,187,176,166,157,148,140,132,125,118,111},
{ 832,785,741,699,660,623,588,555,524,495,467,441, // Tuning 4
416,392,370,350,330,312,294,278,262,247,233,220,
208,196,185,175,165,156,147,139,131,124,117,110},
{ 826,779,736,694,655,619,584,551,520,491,463,437, // Tuning 5
413,390,368,347,328,309,292,276,260,245,232,219,
206,195,184,174,164,155,146,138,130,123,116,109},
{ 820,774,730,689,651,614,580,547,516,487,460,434, // Tuning 6
410,387,365,345,325,307,290,274,258,244,230,217,
205,193,183,172,163,154,145,137,129,122,115,109},
{ 814,768,725,684,646,610,575,543,513,484,457,431, // Tuning 7
407,384,363,342,323,305,288,272,256,242,228,216,
204,192,181,171,161,152,144,136,128,121,114,108},
{ 907,856,808,762,720,678,640,604,570,538,508,480, // Tuning -8
453,428,404,381,360,339,320,302,285,269,254,240,
226,214,202,190,180,170,160,151,143,135,127,120},
{ 900,850,802,757,715,675,636,601,567,535,505,477, // Tuning -7
450,425,401,379,357,337,318,300,284,268,253,238,
225,212,200,189,179,169,159,150,142,134,126,119},
{ 894,844,796,752,709,670,632,597,563,532,502,474, // Tuning -6
447,422,398,376,355,335,316,298,282,266,251,237,
223,211,199,188,177,167,158,149,141,133,125,118},
{ 887,838,791,746,704,665,628,592,559,528,498,470, // Tuning -5
444,419,395,373,352,332,314,296,280,264,249,235,
222,209,198,187,176,166,157,148,140,132,125,118},
{ 881,832,785,741,699,660,623,588,555,524,494,467, // Tuning -4
441,416,392,370,350,330,312,294,278,262,247,233,
220,208,196,185,175,165,156,147,139,131,123,117},
{ 875,826,779,736,694,655,619,584,551,520,491,463, // Tuning -3
437,413,390,368,347,328,309,292,276,260,245,232,
219,206,195,184,174,164,155,146,138,130,123,116},
{ 868,820,774,730,689,651,614,580,547,516,487,460, // Tuning -2
434,410,387,365,345,325,307,290,274,258,244,230,
217,205,193,183,172,163,154,145,137,129,122,115},
{ 862,814,768,725,684,646,610,575,543,513,484,457, // Tuning -1
431,407,384,363,342,323,305,288,272,256,242,228,
216,203,192,181,171,161,152,144,136,128,121,114}};
struct kupa { // user interface
UBYTE modstrt;
UBYTE modstop;
UBYTE speed;
UBYTE patt;
WORD destperd;
UBYTE volume;
UBYTE ciaspeed;
UBYTE ciaon;
UBYTE ntscon;
UBYTE resampling;
UBYTE sustain;
};
struct sampel { // opis sampla
UBYTE volume;
BYTE *smpstrt;
UWORD smpstop;
UWORD repeat;
UWORD repeatlen;
BYTE finetune;
};
char name[108],loadname[108],savename[108],BORING[]="Boring...",defmod[108],defsmp[108];
BOOL running=TRUE,playing=FALSE,mixed=FALSE;
UBYTE whichannel[] = { 1,2,4,8 },*chipptr=NULL;
ULONG class,code,modlen,smplen,device,oldlen,kick;
APTR modptr=0,smpptr=0;
BPTR modhandle,smphandle;
struct IOAudio *AudioIO=NULL;
struct MsgPort *AudioMP=NULL;
struct IntuiMessage *message;
struct Library *ReqToolsBase;
struct DiskObject *icon;
struct rtFileRequester *file_req;
struct rtFileRequester *sfile_req;
struct notes notes[]=
{
"C-1","C#1","D-1","D#1","E-1","F-1","F#1","G-1","G#1","A-1","A#1","B-1",
"C-2","C#2","D-2","D#2","E-2","F-2","F#2","G-2","G#2","A-2","A#2","B-2",
"C-3","C#3","D-3","D#3","E-3","F-3","F#3","G-3","G#3","A-3","A#3","B-3",
};
struct kupa sinfo={0,31,6,0,214,50,125,1,0};
extern struct Library *SysBase;
void main(int argc,char *argv[])
{
kick=SysBase->lib_Version;
if(kick>35)
{
if(ReqToolsBase=OpenLibrary("reqtools.library",0))
{
if(!(icon=TTGetOurIcon(WBenchMsg))) icon=GetDiskObject(argv[0]);
if(icon)
{
strcpy(defmod,TTString(icon,"MODULE","PROGDIR:"));
strcpy(defsmp,TTString(icon,"SAMPLE","PROGDIR:"));
TTFreeOurIcon(icon);
}
if(file_req=rtAllocRequest(RT_FILEREQ,NULL))
{
if(sfile_req=rtAllocRequest(RT_FILEREQ,NULL))
{
rtChangeReqAttr( file_req,RTFI_Dir,defmod);
rtChangeReqAttr(sfile_req,RTFI_Dir,defsmp);
if(OpenAudio())
{
if(!SetupScreen())
{
if(!OpenMainWindow())
{
PrintNote(24);
while(running)
{
Wait(1<<MainWnd->UserPort->mp_SigBit);
HandleMainWnd();
}
CloseMainWindow();
}
else RequestOK("Can't open window");
CloseDownScreen();
}
else RequestOK("Can't setup screen");
CloseAudio();
}
else RequestOK("Can't allocate audio channel");
rtFreeRequest(sfile_req);
}
else RequestOK("Can't allocate requester");
rtFreeRequest(file_req);
}
else RequestOK("Can't allocate requester");
CloseLibrary(ReqToolsBase);
}
else RequestOK("Can't open reqtools.library");
FreeMemory();
}
}
void HandleMainWnd()
{
APTR windowlock;
struct Gadget *gadget;
struct MenuItem *item;
while(message=GT_GetIMsg(MainWnd->UserPort))
{
class = message->Class;
code = message->Code;
gadget = (struct Gadget *)message->IAddress;
GT_ReplyIMsg(message);
switch(class)
{
case IDCMP_CLOSEWINDOW:
running=FALSE;
break;
case IDCMP_MENUPICK:
while(code!=MENUNULL)
{
item = (struct MenuItem *) ItemAddress(MainMenus,code);
switch(ITEMNUM(code))
{
case 0: // About
RequestAbout();
break;
case 2: // Quit
running=FALSE;
break;
}
code=item->NextSelect;
}
break;
case IDCMP_MOUSEMOVE:
switch(gadget->GadgetID)
{
case GD_PATTERN:
sinfo.patt=code;
break;
case GD_START:
sinfo.modstrt=code;
break;
case GD_END:
sinfo.modstop=code;
break;
case GD_CIASPEED:
sinfo.ciaspeed=code;
break;
case GD_VBLSPEED:
sinfo.speed=code;
break;
case GD_FREQUENCY:
PrintNote(code);
sinfo.destperd=periodtab[0][code];
break;
case GD_VOLUME:
sinfo.volume=code;
break;
}
break;
case IDCMP_GADGETUP:
switch(gadget->GadgetID)
{
case GD_QUIT:
running=FALSE;
break;
case GD_LOAD:
windowlock=rtLockWindow(MainWnd);
rtSetWaitPointer(MainWnd);
if(rtFileRequest(file_req,name,"Select file...",
RT_Window, MainWnd,
RT_Underscore, '_',
RT_ReqPos, REQPOS_CENTERSCR,
RTFI_Height, 256,
RTFI_OkText, "_Ok...",
TAG_DONE))
{
strcpy(loadname,file_req->Dir);
if(loadname[strlen(loadname)>0])
if(loadname[strlen(loadname)-1]!=':') strcat(loadname,"/");
strcat(loadname,name);
Status("Loading...");
LoadModule(loadname);
SetDefault(modptr);
Status(BORING);
}
rtUnlockWindow(MainWnd,windowlock);
break;
case GD_SAVE:
windowlock=rtLockWindow(MainWnd);
rtSetWaitPointer(MainWnd);
if(rtFileRequest(sfile_req,name,"Select file...",
RT_Window, MainWnd,
RT_Underscore, '_',
RT_ReqPos, REQPOS_CENTERSCR,
RTFI_Flags, FREQF_SAVE,
RTFI_Height, 256,
RTFI_OkText, "_Ok...",
TAG_DONE))
{
strcpy(savename,sfile_req->Dir);
if(savename[strlen(savename)>0])
if(savename[strlen(savename)-1]!=':') strcat(savename,"/");
strcat(savename,name);
Status("Loading...");
SaveSample(savename);
Status(BORING);
}
rtUnlockWindow(MainWnd,windowlock);
break;
case GD_PLAY: // disabled
// windowlock=rtLockWindow(MainWnd);
// rtSetWaitPointer(MainWnd);
Status("Playing...");
Play();
Status(BORING);
SetTitle();
// rtUnlockWindow(MainWnd,windowlock);
break;
case GD_MIX:
windowlock=rtLockWindow(MainWnd);
rtSetWaitPointer(MainWnd);
Status("Working...");
Work();
Status(BORING);
rtUnlockWindow(MainWnd,windowlock);
break;
case GD_CIA:
sinfo.ntscon=code;
break;
case GD_INTERRUPT:
if(code) sinfo.ciaon=0;
else sinfo.ciaon=1;
break;
case GD_RESAMPLING:
sinfo.resampling=(UBYTE) code;
break;
case GD_PATTERN:
sinfo.patt=code;
break;
case GD_START:
sinfo.modstrt=code;
break;
case GD_END:
sinfo.modstop=code;
break;
case GD_CIASPEED:
sinfo.ciaspeed=code;
break;
case GD_VBLSPEED:
sinfo.speed=code;
break;
case GD_FREQUENCY:
PrintNote(code);
sinfo.destperd=periodtab[0][code];
break;
case GD_VOLUME:
sinfo.volume=code;
break;
case GD_SUSTAIN:
sinfo.sustain=code;
break;
}
break;
}
}
}
void PrintNote(ULONG code)
{
char notetxt[4];
sprintf(notetxt,"%s",notes[code].a);
GT_SetGadgetAttrs(MainGadgets[GD_PITCHTEXT],MainWnd,NULL,GTTX_Text,notetxt,TAG_DONE);
}
void Work()
{
int a;
ULONG *ptr;
if(modptr)
{
// printf(" Module length : %i \n",modlen);
// printf(" Module name : %s \n",modptr);
// printf(" Module mark : %s \n",(ULONG)modptr+1080);
// memset(smpptr,0,2*MAXIM);
ptr=smpptr;
for(a=0;a<MAXIM/2;a++) ptr[a]=0L;
smplen=mixer(sinfo);
}
else
RequestOK("No module in memory");
}
/**********************************\
* *
* Mixer *
* *
\**********************************/
#define FIND_ANYTHING(ptr) (*((ULONG *)(ptr)))
#define FIND_PERIOD(ptr) (*((UWORD *)ptr)&0x0fff)
#define FIND_SMPNUMBER(ptr) (((*ptr)&(0xf0))+((*(ptr+2))>>4))
#define FIND_EFFECT(ptr) ((*(ptr+2))&0x0f)
#define FIND_PARAMETR(ptr) (*(ptr+3))
ULONG mixer(sinfo)
struct kupa sinfo;
{
char text[20];
BYTE *module; // adres moduîu
WORD *fromword; // pointery do zamiany z word'ow na
BYTE *tobyte; // bajty
ULONG len; // koncowa dlugosc sampla
ULONG h,i,j,k; // zmienne do organizacji petli
UWORD hipatt=0; // tu bedzie ilosc pattern'ów
ULONG ilenapoz; // ile sampla wygenerowac
// do nastepnej pozycji
WORD *ptr2smp; // pointery do generowania
WORD *ptr2smppom; // zmiksowanego sampla ( w word'ach)
UBYTE *ptr2mod; // pointer do przesuwania sie
// po module
UBYTE speed; // aktualna predkosc
UBYTE ciaspeed;
UBYTE ilepozycji; // ile pozycji do zrobienia
UWORD pomoc;
WORD pom;
WORD probka0,probka1;
UBYTE sust;
struct sampel smp[32]; // tablica pointerow do sampli
struct canal { // co sie dzieje w kanale
BYTE nrsmp; // numer odgrywanego sampla
BYTE volume; // gîoônoôê sampla
WORD period; // period
ULONG jump;
ULONG jumppos;
UWORD smppos;
BYTE *smpstrt;
UWORD smpstop;
UWORD smprepeat;
UWORD smprepeatlen;
BYTE volslide; // do komendy - Axx
UBYTE last9; // do komendy - 9xx
UBYTE actE9; // do komendy - E9x
UBYTE notecut; // do komendy - ECx
WORD trgetperd; // do komendy - 3xx
WORD toneslide; // ----------------
WORD lasttrget; // ----------------
WORD lasttonesl; // ----------------
UBYTE arpeggio; // do komendy - 0xx
WORD saveperd; // ----------------
};
struct canal chan[4]={{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
struct line {
ULONG anything;
WORD period;
UBYTE smpnumber;
UBYTE effect;
UBYTE parametr;
};
struct line trackline[4];
sust=sinfo.sustain;
module=modptr;
ptr2smp=smpptr;
hipatt=policzpatterny(module);
adresysampli(module,smp,hipatt);
speed=sinfo.speed;
ciaspeed=sinfo.ciaspeed;
if(sust){
ilepozycji=sinfo.modstop+1;
ptr2mod=module+1084+1024*sinfo.patt; // ustawienie sie na odpowiednia pozycje
}
else{
ilepozycji=sinfo.modstop-sinfo.modstrt+1;
ptr2mod=module+1084+1024*sinfo.patt+16*sinfo.modstrt; // ustawienie sie na odpowiednia pozycje
}
// if(debug) printf(" Destination Period = %i\n",sinfo.destperd);
// printf(" Wow! There will be %i positions. \n >",ilepozycji);
for(h=0;h<=(ilepozycji-1);h++){
if((sust)&&(h>=sinfo.modstrt)) sust=0;
for(i=0;i<=3;i++){
trackline[i].anything = (ULONG)FIND_ANYTHING(ptr2mod);
trackline[i].period = (WORD)FIND_PERIOD(ptr2mod);
trackline[i].smpnumber = (UBYTE)FIND_SMPNUMBER(ptr2mod);
trackline[i].effect = (UBYTE)FIND_EFFECT(ptr2mod);
trackline[i].parametr = (UBYTE)FIND_PARAMETR(ptr2mod);
ptr2mod=ptr2mod+4;
}
// if(debug){
// printf("\n");
// for(i=0;i<=3;i++){
// if(trackline[i].period) printf(" J-4");
// else printf(" ---");
// printf("%2x%1x%2x",trackline[i].smpnumber,trackline[i].effect,trackline[i].parametr);
// }
// }
for(i=0;i<=3;i++){
chan[i].volslide=0;
chan[i].actE9=0;
chan[i].toneslide=0;
chan[i].arpeggio=0;
chan[i].saveperd=0;
if(trackline[i].smpnumber){
chan[i].nrsmp=trackline[i].smpnumber;
chan[i].volume=smp[chan[i].nrsmp].volume;
}
pomoc=0;
if(trackline[i].effect==0x03) pomoc=1;
if(trackline[i].effect==0x05) pomoc=1;
if( (trackline[i].period)&&(pomoc==0) ){
chan[i].period=trackline[i].period;
chan[i].trgetperd=0;
if( smp[chan[i].nrsmp].finetune)
chan[i].period = findperiod( chan[i].period, smp[chan[i].nrsmp].finetune,0);
chan[i].smpstrt=smp[chan[i].nrsmp].smpstrt;
chan[i].smpstop=smp[chan[i].nrsmp].smpstop;
chan[i].smprepeat=smp[chan[i].nrsmp].repeat;
chan[i].smprepeatlen=smp[chan[i].nrsmp].repeatlen;
chan[i].smppos=0;
chan[i].jumppos=0;
}
switch(trackline[i].effect){
case 0x0f:
if( (sinfo.ciaon)&&(trackline[i].parametr>0x1f) )
ciaspeed=trackline[i].parametr;
else
speed=trackline[i].parametr;
break;
case 0x0e:
switch(trackline[i].parametr>>4){
case 0x09:
chan[i].actE9=trackline[i].parametr&0x0f;
break;
case 0x0a:
chan[i].volume+=trackline[i].parametr&0x0f;
break;
case 0x0b:
chan[i].volume-=trackline[i].parametr&0x0f;
break;
case 0x0c:
chan[i].notecut=(trackline[i].parametr&0x0f)+1;
break;
case 0x02:
chan[i].period+=trackline[i].parametr&0x0f;
if( chan[i].period>findperiod(856,smp[chan[i].nrsmp].finetune,0) )
chan[i].period=findperiod(856,smp[chan[i].nrsmp].finetune,0);
break;
case 0x01:
chan[i].period-=trackline[i].parametr&0x0f;
if( chan[i].period<findperiod(113,smp[chan[i].nrsmp].finetune,0) )
chan[i].period=findperiod(113,smp[chan[i].nrsmp].finetune,0);
break;
}
break;
case 0x0c:
chan[i].volume=trackline[i].parametr;
break;
case 0x0a:
if( (trackline[i].parametr)&0xf0)
chan[i].volslide=(trackline[i].parametr>>4)&0x0f;
else
chan[i].volslide=-trackline[i].parametr;
break;
case 0x09:
if(trackline[i].parametr)
chan[i].last9=trackline[i].parametr;
pomoc=((UWORD)chan[i].last9)<<8;
if(pomoc>(chan[i].smpstop))
chan[i].smppos=chan[i].smprepeat;
else
chan[i].smppos=pomoc;
chan[i].jumppos=0;
break;
case 0x05:
if( (trackline[i].parametr)&0xf0)
chan[i].volslide=(trackline[i].parametr>>4)&0x0f;
else
chan[i].volslide=-trackline[i].parametr;
if(trackline[i].period){
chan[i].trgetperd=findperiod(trackline[i].period,smp[chan[i].nrsmp].finetune,0);
chan[i].lasttrget=chan[i].trgetperd;
}
else{
chan[i].trgetperd=chan[i].lasttrget;
}
if( chan[i].period>chan[i].trgetperd )
chan[i].toneslide=-chan[i].lasttonesl;
else
chan[i].toneslide=chan[i].lasttonesl;
if(chan[i].trgetperd==0) chan[i].toneslide=0;
break;
case 0x03:
if(trackline[i].period){
chan[i].trgetperd=findperiod(trackline[i].period,smp[chan[i].nrsmp].finetune,0);
chan[i].lasttrget=chan[i].trgetperd;
}
else{
chan[i].trgetperd=chan[i].lasttrget;
}
chan[i].lasttonesl=trackline[i].parametr;
if( chan[i].period>chan[i].trgetperd )
chan[i].toneslide=-trackline[i].parametr;
else
chan[i].toneslide=trackline[i].parametr;
if(chan[i].trgetperd==0) chan[i].toneslide=0;
break;
case 0x02:
chan[i].trgetperd=findperiod(856,smp[chan[i].nrsmp].finetune,0);
chan[i].toneslide=trackline[i].parametr;
break;
case 0x01:
chan[i].trgetperd=findperiod(113,smp[chan[i].nrsmp].finetune,0);
chan[i].toneslide=-trackline[i].parametr;
break;
case 0x00:
if(trackline[i].parametr){
chan[i].arpeggio=trackline[i].parametr;
chan[i].saveperd=chan[i].period;
}
break;
}
}
// ile probek
if(sinfo.ciaon){
if(sinfo.ntscon)
ilenapoz=((CIAVALNTSC*5)/ciaspeed)/sinfo.destperd;
else
ilenapoz=((CIAVAL*5)/ciaspeed)/sinfo.destperd;
}
else{
if(sinfo.ntscon)
ilenapoz=VBLVALNTSC/sinfo.destperd;
else
ilenapoz=VBLVAL/sinfo.destperd;
}
// mixowanie
for(i=0;i<=3;i++){
ptr2smppom=ptr2smp;
//printf("\n");
for(k=0;k<=(speed-1);k++){
// comman E9x retrig note
if(chan[i].actE9){
if( (k-(k/chan[i].actE9)*chan[i].actE9)==0 ){
chan[i].smppos=0;
chan[i].jumppos=0;
chan[i].smpstop=smp[chan[i].nrsmp].smpstop;
}
}
// comman ECx note cut
if(chan[i].notecut){
if( k==(chan[i].notecut-1) ){
chan[i].volume=0;
}
}
// command Axx volsliding
if((chan[i].volslide)&&(k!=0)){
chan[i].volume=chan[i].volume+chan[i].volslide;
if(chan[i].volume<0) chan[i].volume=0;
if(chan[i].volume>64) chan[i].volume=64;
}
// command 3xx tone sliding
if((chan[i].toneslide)&&(k!=0)){
//printf("!");
chan[i].period+=chan[i].toneslide;
if(chan[i].toneslide<0){
if(chan[i].period<chan[i].trgetperd)
chan[i].period=chan[i].trgetperd;
}
else{
if(chan[i].period>chan[i].trgetperd)
chan[i].period=chan[i].trgetperd;
}
}
// command 0xx arpeggio
if(chan[i].arpeggio){
switch( k-(k/3)*3 ){
case 2:
chan[i].period=findperiod( chan[i].saveperd, smp[chan[i].nrsmp].finetune, chan[i].arpeggio&0x0f);
break;
case 1:
chan[i].period=findperiod( chan[i].saveperd, smp[chan[i].nrsmp].finetune, chan[i].arpeggio>>4);
break;
case 0:
chan[i].period=chan[i].saveperd;
break;
}
}
//printf(" %i",chan[i].period);
if(chan[i].period!=0)
chan[i].jump=(((ULONG)sinfo.destperd)<<16)/chan[i].period;
else
chan[i].jump=0;
// generowanie sampla
for(j=0;j<=ilenapoz;j++){
if((ULONG)ptr2smppom>=(ULONG)smpptr+MAXIM*2) break; // jesli przekroczymy bufor to stop
chan[i].smppos+=(UWORD)(chan[i].jumppos>>16);
chan[i].jumppos=chan[i].jumppos&0xffff;
if(chan[i].smppos>=chan[i].smpstop){
chan[i].smppos=chan[i].smprepeat+(chan[i].smppos-chan[i].smpstop);
chan[i].smpstop=chan[i].smprepeat+chan[i].smprepeatlen;
}
probka0=*(chan[i].smppos+chan[i].smpstrt);
probka1=*(chan[i].smppos+chan[i].smpstrt+1);
if((chan[i].smppos+1)>=chan[i].smpstop){
probka1=*(chan[i].smprepeat+chan[i].smpstrt);
}
pom=calculate_pom(probka0,probka1,chan[i].jumppos,chan[i].jump,sinfo.resampling);
if(sust==0){
*ptr2smppom+=(pom*chan[i].volume)/64;
ptr2smppom++;
}
chan[i].jumppos+=chan[i].jump;
}
}
if(chan[i].saveperd){
chan[i].period=chan[i].saveperd;
}
}
ptr2smp=ptr2smppom;
// printf("*");
}
// printf("\n");
// obcinanie
len=((ULONG)ptr2smp-(ULONG)smpptr)/2;
fromword=smpptr;
tobyte=smpptr;
for(i=0;i<=len;i++){
pom=((*fromword++)*sinfo.volume)/100;
if(pom>127) pom=127;
if(pom<-128) pom=-128;
*tobyte++=pom;
if((i>>10)<<10==i)
{
sprintf(text,"%i",i);
Status(text);
}
// printf("\r hmm ... : %i ",i);
}
// printf("\r OK it's: %i \n",i);
sprintf(text,"%i",i);
Status(text);
mixed=TRUE;
return(len);
}
WORD findperiod(mainperiod,finetune,index)
WORD mainperiod;
BYTE finetune;
BYTE index;
{
UWORD i;
for(i=0;i<=12*3;i++)
if(mainperiod==periodtab[0][i]) break;
i=i+index;
if(i>=12*3) return(0);
return(periodtab[finetune][i]);
}
WORD calculate_pom(sample0,sample1,jumppos,jump,method)
WORD sample0;
WORD sample1;
ULONG jumppos;
ULONG jump;
UBYTE method;
{
WORD a;
WORD i;
ULONG myjumppos;
if(jump==0)
return(0);
myjumppos=jumppos;
if(method){
for(i=1;(jump)<(0x10000/(i+1));i++);
//printf("i= %i\n",i);
if(i>1){
if(jumppos<((0x10000/i)*(i-1)))
return(sample0);
else{
myjumppos=(jumppos-((0x10000/i)*(i-1)))*i;
}
}
}
a=sample1-sample0;
a=(WORD)(((LONG)myjumppos*a)>>16);
a=a+sample0;
return(a);
}
UWORD policzpatterny(module)
BYTE *module;
{
UWORD pomoc;
UWORD i;
UWORD hipat=0;
for(i=0;i<=127;i++){
pomoc=*((UBYTE *)(module+952+i));
hipat=(hipat>pomoc)?hipat:pomoc;
}
hipat++;
return(hipat);
}
void adresysampli(module,smp,hipatt)
BYTE *module;
struct sampel smp[]; // tablica pointerow do sampli
UWORD hipatt;
{
UWORD i;
UWORD pomoc;
smp[1].smpstrt=module+1084+1024*hipatt;
smp[1].smpstop=(*((UWORD *)(module+42)))*2;
smp[1].volume=*((UBYTE *)(module+45));
smp[1].repeat=(*((UWORD *)(module+46)))*2;
smp[1].repeatlen=(*((UWORD *)(module+48)))*2;
smp[1].finetune=*((UBYTE *)(module+44));
for(i=2;i<=31;i++){
pomoc=*((UWORD *)(module+42+30*(i-2)));
smp[i].smpstrt=smp[i-1].smpstrt+pomoc*2;
smp[i].smpstop=(*((UWORD *)(module+42+30*(i-1))))*2;
smp[i].volume=*((UBYTE *)(module+45+30*(i-1)));
smp[i].repeat=(*((UWORD *)(module+46+30*(i-1))))*2;
smp[i].repeatlen=(*((UWORD *)(module+48+30*(i-1))))*2;
smp[i].finetune=*((UBYTE *)(module+44+30*(i-1)));
if(smp[i].repeat) smp[i].smpstop=smp[i].repeat+smp[i].repeatlen;
}
// if(debug){
// for(i=1;i<=8;i++)
// printf(" %2i. vol %-2x strt $%-6x stop $%-4x %-5i repeat $%-4x repeatlen $%-4x \n",i,smp[i].volume,smp[i].smpstrt,smp[i].smpstop,smp[i].smpstop,smp[i].repeat,smp[i].repeatlen);
// }
}
/*------------------------------------------------------------------------------*/
void RequestOK(char *what)
{
APTR windowlock;
windowlock=rtLockWindow(MainWnd);
rtSetWaitPointer(MainWnd);
rtEZRequestTags(what,"_Ok",NULL,NULL,RT_Underscore,'_',RT_Window,MainWnd,TAG_DONE);
rtUnlockWindow(MainWnd,windowlock);
}
void RequestAbout()
{
APTR windowlock;
windowlock=rtLockWindow(MainWnd);
rtSetWaitPointer(MainWnd);
rtEZRequestTags(ABOUTTXT,"_Ok",NULL,NULL,RT_Underscore,'_',
RT_Window,MainWnd,
RTEZ_Flags,EZREQF_CENTERTEXT,
TAG_DONE);
rtUnlockWindow(MainWnd,windowlock);
}
void LoadModule(char *filename)
{
FreeMemory();
if(modhandle=Open(filename,MODE_OLDFILE))
{
Seek(modhandle,0,OFFSET_END);
modlen=Seek(modhandle,0,OFFSET_BEGINNING);
if(modptr=AllocMem(modlen,MEMF_PUBLIC))
{
Read(modhandle,modptr,modlen);
if(*((ULONG *)((ULONG)modptr+1080))!=*((ULONG *)"M.K."))
{
RequestOK("This is not a ProTracker module");
FreeMem(modptr,modlen);
modptr=0;
}
if(!(smpptr=AllocMem(MAXIM*2,MEMF_CLEAR|MEMF_PUBLIC)))
{
RequestOK("Not enough memory to allocate sample buffer.");
FreeMem(smpptr,MAXIM*2);
modptr=0;
}
mixed=FALSE;
}
else
RequestOK("Not enough memory");
Close(modhandle);
}
else
RequestOK("Can't open module");
}
void SaveSample(char *filename)
{
if(modptr && smpptr)
{
if(smphandle=Open(filename,MODE_NEWFILE))
{
if(Write(smphandle,smpptr,smplen)==-1)
{
RequestOK("Can't save file.");
}
Close(smphandle);
}
else
RequestOK("Can't open file to save");
}
}
void FreeMemory()
{
if(modptr) FreeMem(modptr,modlen);
modptr=0;
if(smpptr) FreeMem(smpptr,MAXIM*2);
smpptr=0;
}
void Status(char *text)
{
GT_SetGadgetAttrs(MainGadgets[GD_STATUS],MainWnd,NULL,GTTX_Text,text,TAG_DONE);
}
BOOL OpenAudio()
{
if(AudioMP = CreatePort(0,0))
{
if(AudioIO=(struct IOAudio *)CreateExtIO(AudioMP,sizeof(struct IOAudio)))
{
AudioIO->ioa_Request.io_Command = ADCMD_ALLOCATE;
AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri = 50;
AudioIO->ioa_AllocKey = 0;
AudioIO->ioa_Data = whichannel;
AudioIO->ioa_Length = sizeof(whichannel);
if(!(device=OpenDevice(AUDIONAME,0L, (struct IORequest *) AudioIO ,0L)))
{
return(1);
}
}
}
return(0);
}
void CloseAudio()
{
if (device == 0) CloseDevice((struct IORequest *) AudioIO);
if (AudioIO != 0) DeleteExtIO((struct IORequest *)AudioIO);
if (AudioMP != 0) DeletePort(AudioMP);
}
void Play()
{
if(playing)
{
AbortIO((struct IORequest *)AudioIO);
playing=FALSE;
if(chipptr) FreeMem(chipptr,oldlen);
chipptr=NULL;
}
else
{
if(mixed)
{
if(smpptr)
{
if(chipptr=AllocMem(smplen,MEMF_CHIP))
{
playing=TRUE;
oldlen=smplen;
CopyMem(smpptr,(APTR) chipptr,smplen);
AudioIO->ioa_Request.io_Command=CMD_WRITE;
AudioIO->ioa_Request.io_Flags =ADIOF_PERVOL;
AudioIO->ioa_Data =chipptr;
AudioIO->ioa_Length=smplen;
AudioIO->ioa_Period=sinfo.destperd;
AudioIO->ioa_Volume=64;
AudioIO->ioa_Cycles=0;
BeginIO((struct IORequest *)AudioIO);
// WaitIO((struct IORequest *)AudioIO);
// AbortIO((struct IORequest *)AudioIO);
// FreeMem(chipptr,smplen);
}
}
}
else
RequestOK("No sample in memory");
}
}
void SetDefault(APTR modptr)
{
UWORD patts;
patts=policzpatterny(modptr);
GT_SetGadgetAttrs(MainGadgets[GD_PATTERN],MainWnd,NULL,GTSL_Max,(ULONG)patts-1,TAG_DONE);
}
void SetTitle()
{
// if(playing) MainGadgets[GD_PLAY]->GadgetText="Stop";
// else MainGadgets[GD_PLAY]->GadgetText="Play";
// GT_RefreshWindow(MainWnd,NULL);
}